package com.oba.base.util;

import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.MethodExpression;
import javax.el.ValueExpression;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import javax.servlet.jsp.JspException;

import org.apache.velocity.tools.generic.EscapeTool;

import com.oba.base.convertor.ConvertUtil;
import com.oba.base.dao.BaseDao;
import com.oba.base.interfaces.IBaseBo;
import com.oba.base.service.BaseBo;
import com.oba.king.login.UserInfo;
import com.oba.king.sysmanager.log.Log;
import com.oba.king.sysmanager.log.TableInfo;
import com.oba.king.sysmanager.log.TableService;

public class Util {
	/**
	 * 动态执行
	 * 
	 * @param hostobj
	 *            宿主对象
	 * @param methodname
	 *            执行方法名称
	 * @param params
	 *            实际的执行参数
	 * @return 执行结果
	 */
	public static Object dynamicExecute(Object hostobj, String methodname, Object[] params) {
		Class hostclass = hostobj.getClass();
		Class[] paramCls = new Class[params.length];
		for (int i = 0; i < params.length; i++) {
			paramCls[i] = params[i].getClass();
		}
		try {
			Method method = hostclass.getMethod(methodname, paramCls);
			return method.invoke(hostobj, params);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * JSP中属性值不能为空
	 * 
	 * @param attName
	 *            属性名称
	 * @param AttValue
	 *            属性值
	 * @throws JspException
	 */
	public static void MustNotNull(String attName, String AttValue) throws JspException {
		if (AttValue == null)
			throw new JspException("attribute: " + attName + " must not be null!");
	}

	/**
	 * 取得指定日期的第二天
	 * 
	 * @param date
	 * @return
	 */
	public static Date Tomorrow(Date date) {
		if (date == null)
			return null;
		Calendar ca = Calendar.getInstance();
		ca.setTime(date);
		ca.add(Calendar.DAY_OF_MONTH, 1);
		return ca.getTime();
	}

	/**
	 * 获取当前时间
	 * 
	 * @return
	 */
	public static Date getCurTime() {
		return Calendar.getInstance().getTime();
	}

	/**
	 * 获得特定日期指定月份数后的日期
	 * 
	 * @param inDate
	 *            特定日期
	 * @param months
	 *            指定月份数
	 * @return
	 */
	public static Date addMonths(Date inDate, Long months) {
		if (inDate == null || months == null) {
			return null;
		} else {
			Calendar ca = Calendar.getInstance();
			ca.setTime(inDate);
			ca.add(Calendar.MONTH, months.intValue());
			return ca.getTime();
		}
	}

	/**
	 * 获得特定日期指定天数后的日期
	 * 
	 * @param inDate
	 *            特定日期
	 * @param days
	 *            指定天数
	 * @return
	 */
	public static Date addDays(Date inDate, Long days) {
		if (inDate == null || days == null) {
			return null;
		} else {
			Calendar ca = Calendar.getInstance();
			ca.setTime(inDate);
			ca.add(Calendar.DAY_OF_MONTH, days.intValue());
			return ca.getTime();
		}
	}

	private static EscapeTool escapeTool = new EscapeTool();

	/**
	 * 将java字符串转换化Javascript所对应的字符串
	 * 
	 * @param inputObj
	 *            被转换对象
	 * @return Javascript对象所对应的字符串
	 */
	public static String escapeToJavascript(Object inputObj) {
		return escapeTool.javascript(inputObj);
	}

	static private DateFormat yearFormat = new SimpleDateFormat("yyyy");

	/**
	 * 取得当前年份
	 * 
	 * @return 当前年份
	 */
	public static String getCurYear() {
		return yearFormat.format(Util.getCurTime());
	}

	static private DateFormat monthFormat = new SimpleDateFormat("yyyy-MM");

	/**
	 * 取得当前月份
	 * 
	 * @return 当前月份
	 */
	public static String getCurYearMonth() {
		return monthFormat.format(Util.getCurTime());
	}

	public static List<SelectItem> getSelectItems(List<? extends IBaseBo> bos) {
		List<SelectItem> items = new ArrayList<SelectItem>();
		if (bos != null) {
			for (int i = 0; i < bos.size(); i++) {
				IBaseBo bo = bos.get(i);
				items.add(new SelectItem(bo, bo.getName()));
			}
		}
		return items;
	}

	public static String getObjectExpress(String beanName, String attrName) {
		StringBuilder builder = new StringBuilder("#{");
		builder.append(beanName);
		if (attrName != null) {
			builder.append(".");
			builder.append(attrName);
		}
		builder.append("}");
		return builder.toString();
	}

	static public Object getBean(String beanName) {
		FacesContext context = FacesContext.getCurrentInstance();
		ExpressionFactory expFactory = context.getApplication().getExpressionFactory();
		ELContext elcontext = context.getELContext();
		ValueExpression ve = expFactory
				.createValueExpression(elcontext, getObjectExpress(beanName, null), Object.class);
		return ve.getValue(elcontext);
		/*
		 * ServletContext servletContext = (ServletContext) FacesContext
		 * .getCurrentInstance().getExternalContext().getContext();
		 * ApplicationContext appContext = WebApplicationContextUtils
		 * .getWebApplicationContext(servletContext); return
		 * appContext.getBean(beanName);
		 */
	}

	private static final String BEAN_NAME = "bean=";
	private static final String INVOCATION_METHOD = "method=";

	public static boolean beanInit(FacesContext context, String InitStr) {
		if (InitStr == null)
			return false;
		String[] urlParams = InitStr.split("&");
		if (urlParams.length < 2)
			return false;
		if (urlParams[0].startsWith(BEAN_NAME) && urlParams[1].startsWith(INVOCATION_METHOD)) {
			ExpressionFactory expFactory = context.getApplication().getExpressionFactory();
			ELContext elcontext = context.getELContext();
			String beanName = urlParams[0].split("=")[1].trim();
			String method = urlParams[1].split("=")[1].trim();
			for (int i = 2; i < urlParams.length; i++) {
				String[] nameValue = urlParams[i].split("=");
				if (nameValue.length < 2)
					continue;
				try {
					ValueExpression ve = expFactory.createValueExpression(elcontext, Util.getObjectExpress(beanName,
							nameValue[0].trim()), Object.class);
					ve.setValue(elcontext, ConvertUtil.convert(ve.getType(elcontext), nameValue[1].trim()));
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			MethodExpression me = expFactory.createMethodExpression(elcontext, Util.getObjectExpress(beanName, method),
					null, new Class<?>[0]);
			me.invoke(elcontext, null);
			return true;
		} else
			return false;
	}

	static public String numberFormat(Number num, int len) {
		DecimalFormat df = new DecimalFormat();
		df.setMinimumIntegerDigits(len);
		df.setGroupingUsed(false);
		df.setMaximumFractionDigits(0);
		return df.format(num);
	}

	public static Map<String, Object> getSessionMap() {
		return FacesContext.getCurrentInstance().getExternalContext().getSessionMap();
	}

	public static String idsFormat(List<Long> list) {
		StringBuffer sb = new StringBuffer();
		sb.append("(");
		int len = list.size();
		for (int i = 0; i < len; i++) {
			Long l = list.get(i);
			if(l == null){
				continue;
			}
			sb.append(l.longValue());
			if (i != len - 1) {
				sb.append(",");
			}
		}
		sb.append(")");
		String rStr = sb.toString();
		if (rStr.length() < 3) {
			rStr = "(0)";
		}
		return rStr;
	}
	
	public static String idsFormatByBo(List<? extends IBaseBo> list) {
		List<Long> longList = new ArrayList<Long>();
		for(IBaseBo bo:list) {
			if(bo.getId() == null) {
				continue;
			}
			longList.add(bo.getId());
		}
		return idsFormat(longList);
	}
	
	/**
	 * 记录日志
	 */
	public void saveLog(IBaseBo bo,int type) {
		BaseDao baseDao = (BaseDao) getSessionMap().get("baseDao");
		baseDao.saveLog(bo, type);
	}
	
}
